/*
 * Copyright 2016-2019 yoara
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package yhao.infra.common.config;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import yhao.infra.common.InfraCommonConstants;
import yhao.infra.common.YhaoInfraCommonProperties;
import yhao.infra.common.cache.CacheOpeType;
import yhao.infra.common.cache.YhaoCache;
import yhao.infra.common.cache.redis.RedisCacheImpl;

import java.util.HashMap;
import java.util.Map;

import static yhao.infra.common.ConfigFactory.makeJedisConnectionFactory;
import static yhao.infra.common.ConfigFactory.makeRedisTemplate;

/**
 * 架构默认的缓存配置类
 *
 * @author yoara
 */
@ConditionalOnProperty(value = YhaoInfraCommonProperties.REDIS_ENABLE,havingValue = "true",matchIfMissing = true)
@ConditionalOnClass(redis.clients.jedis.Jedis.class)
public class RedisConfig {
    @Autowired
    private Environment env;

    @Bean(name = InfraCommonConstants.COMMON_CACHE_BEAN_NAME)
    public YhaoCache redisCache(YhaoInfraCommonProperties properties,
            RedisTemplate redisTemplate, RedisTemplate redisTemplateQuery) {
        Map<String, RedisTemplate<String, Object>> redisMap = new HashMap<>();
        redisMap.put(CacheOpeType.SAVE.name(), redisTemplate);
        redisMap.put(CacheOpeType.QUERY.name(), redisTemplateQuery);

        YhaoCache redisCache = new RedisCacheImpl(redisMap);
        String appName = env.getProperty(YhaoInfraCommonProperties.ENV_APP_NAME);
        if(!StringUtils.isEmpty(appName)){
            redisCache.setSystemUnique(appName.toUpperCase());
        }
        ((RedisCacheImpl) redisCache).setUseRedisSessionBase(properties.isUseRedisSessionBase());
        return redisCache;
    }

    @Bean(name = "redisTemplate")
    public RedisTemplate redisTemplate(JedisConnectionFactory jedisConnectionFactory) {
        return makeRedisTemplate(jedisConnectionFactory);
    }

    @Bean(name = "redisTemplateQuery")
    public RedisTemplate redisTemplateQuery(JedisConnectionFactory jedisConnectionFactoryQuery) {
        return makeRedisTemplate(jedisConnectionFactoryQuery);
    }

    @Bean(name = "stringRedisTemplate")
    public StringRedisTemplate stringRedisTemplate(JedisConnectionFactory jedisConnectionFactory) {
        StringRedisTemplate redisTemplate = new StringRedisTemplate();
        redisTemplate.setConnectionFactory(jedisConnectionFactory);
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        return redisTemplate;
    }

    @Bean(name = "jedisConnectionFactory")
    public JedisConnectionFactory jedisConnectionFactory(YhaoInfraCommonProperties properties) {
        JedisConnectionFactory factory = makeJedisConnectionFactory(properties.getSaveRedis());
        return factory;
    }

    @Bean(name = "jedisConnectionFactoryQuery")
    public JedisConnectionFactory jedisConnectionFactoryQuery(YhaoInfraCommonProperties properties) {
        JedisConnectionFactory queryFactory = makeJedisConnectionFactory(
                properties.isQueryUseSaveProperties()?properties.getSaveRedis():properties.getQueryRedis());
        return queryFactory;
    }
}
